home *** CD-ROM | disk | FTP | other *** search
- /************/
- /**SoundZAP**/
- /************/
-
- /*
- * This program was compiled with Matthew Dillon's DICE C compiler, which
- * automatically opens and closes the Amiga libraries as they are needed.
- * If your compiler does not do this you will have to Add the appropriate
- * code (or get DICE!!).
- */
-
-
- #include "SoundZAP.h"
-
- void main(int argc, char *argv[])
- {
- char comline[33];
- struct options *Opt;
-
-
- if (argc<2) GiveUsage();
-
- printf(SZVER);
- printf(" -- 3 June 1992 -- (c) Michael Cramer\n\n");
-
- if ((Opt=(struct options *)malloc(sizeof(struct options)))==NULL)
- CleanUp(Opt,5);
-
- Opt->BuffSize = DEFAULT_SIZE;
- Opt->Size = 0;
- Opt->InSign = TRUE;
- Opt->OutSign = TRUE;
- Opt->KillChunk = FALSE;
- Opt->FibDeltIn = FALSE;
- Opt->MuLawIn = FALSE;
- Opt->MuLawOut = FALSE;
- Opt->SampRate = 0;
- Opt->NewRate = 0;
- Opt->Data = NULL;
- Opt->Amp = 3;
- Opt->Bits = 8;
- Opt->InType = UNKNOWN;
- Opt->OutType = IFF;
- Opt->inname[0] = '\0';
- Opt->outname[0] = '\0';
- Opt->FileName[0] = '\0';
- Opt->Auth = NULL;
- Opt->Copy = NULL;
-
- while (--argc > 0)
- {
- strcpy(comline,argv[argc]);
- if (comline[0]=='-')
- ProcessOpt(Opt,comline);
- else
- {
- strcpy(Opt->outname,Opt->inname);
- strcpy(Opt->inname,comline);
- }
- }
-
- if (strlen(Opt->inname)==0)
- GiveUsage();
-
- if (strlen(Opt->outname)==0)
- {
- int l;
-
- strcpy(Opt->outname,Opt->inname);
- l=strlen(Opt->outname);
- if(Opt->outname[l-4]=='.')
- Opt->outname[l-4]='\0';
- if(Opt->outname[l-3]=='.')
- Opt->outname[l-3]='\0';
- AFlag=TRUE;
- }
- else
- AFlag=FALSE;
- strcpy(Opt->FileName,Opt->outname);
- AnalyzeData(Opt);
- CleanUp(Opt,0);
- }
-
-
- void GiveUsage()
- {
- printf(SZVER);
- printf("\nUsage: SoundZAP [<options>] SOURCE [DESTINATION]\n");
- printf(" (actually, the options can appear anywhere)\n\n");
- printf(" options -a<n> Amplify by n/3 times\n");
- printf("\t\t-b<n> Use a buffer size of n kilobytes\n");
- printf("\t\t-c<n> Physically resample data to n\n");
- printf("\t\t-f Assume input data is RAW\n");
- printf("\t\t-l Output u-lawed data\n");
- printf("\t\t-n Don't create extra chunks in IFF output\n");
- printf("\t\t-r<n> Change sample rate to n\n");
- printf("\t\t-s Output a Sun .au file\n");
- printf("\t\t-u Output UNSIGNED data\n");
- printf("\t\t-w Output RAW data\n");
- printf("\nSee documentation for more info.\n");
- printf("mrc113@psuvm.psu.edu\n");
- exit(0);
- }
-
- void ProcessOpt(struct options *Opt, char com[])
- {
- int len;
-
- switch (com[1])
- {
- case 'a' : len=strlen(com)-2;
- if (len==0)
- Opt->Amp=0;
- Opt->Amp=(UBYTE)atoi(com+2);
- break;
-
- case 'b' : len=strlen(com)-2;
- if (len==0)
- Opt->BuffSize=0;
- Opt->BuffSize=(ULONG)atoi(com+2)*1024;
- break;
-
- case 'c' : Opt->NewRate = GetRateFromString(Opt, com+2);
- break;
-
- case 'f' : Opt->InType=RAW;
- break;
-
- case 's' : Opt->OutType=AU;
- Opt->MuLawOut=TRUE;
- Opt->NewRate=8000;
- break;
-
- case 'w' : Opt->OutType=RAW;
- break;
-
- case 'l' : Opt->MuLawOut=TRUE;
- break;
-
- case 'n' : Opt->KillChunk=TRUE;
- break;
-
- case 'r' : Opt->SampRate = GetRateFromString(Opt, com+2);
- break;
-
- case 'u' : Opt->OutSign=FALSE;
- break;
-
- default : CleanUp(Opt,4);
- }
- }
-
- UWORD GetRateFromString(struct options *Opt, char *c)
- {
- int len;
- UWORD n;
-
- len=strlen(c);
- if (len==0)
- CleanUp(Opt,3);
- if (len==1)
- {
- switch (c[0])
- {
- case '5' : n=5696;
- break;
-
- case '7' : n=7596;
- break;
-
- case '8' : n=8000;
- break;
-
- case '2' : n=22790;
- break;
-
- default : n=11395;
- }
- }
- else
- {
- n=(UWORD)atoi(c);
- if (!n) n=11395;
- }
- return n;
- }
-
- void CleanUp(struct options *Opt, int Error)
- {
- if (Opt->Data) free(Opt->Data);
- if (Opt->Auth) free(Opt->Auth);
- if (Opt->Copy) free(Opt->Copy);
- if (Opt) free(Opt);
- if (in) Close(in);
- if (out) Close(out);
- if (Error==0) exit(0);
- else
- {
- printf("%s",ErrorMessages[Error]);
- exit(20);
- }
- }
-
- void AnalyzeData(struct options *Opt)
- {
- ULONG MagicWord;
- char IsMac[8];
-
- if ((in=(struct FileHandle *)Open(Opt->inname,MODE_OLDFILE))==NULL)
- CleanUp(Opt,6);
-
- if(Opt->BuffSize==0)
- {
- Seek(in,0,OFFSET_END);
- Opt->BuffSize = (Seek(in,0,OFFSET_BEGINNING) + 1) & ~1;
- }
-
- if ((Opt->Data=(BYTE *)malloc(Opt->BuffSize))==NULL)
- CleanUp(Opt,5);
-
- Read(in,&MagicWord,4);
- if (Opt->InType==UNKNOWN)
- {
- if (MagicWord==0x2e736e64) /* '.snd' */
- ConvertAU(Opt);
- else if (MagicWord==0x464f524d) /* 'FORM' */
- ConvertIFF(Opt);
- else if (MagicWord==0x43726561) /* 'Crea' */
- ConvertVOC(Opt);
- else if (MagicWord==0x52494646) /* 'RIFF' */
- ConvertWAV(Opt);
- else
- {
- Seek(in,65,OFFSET_BEGINNING);
- Read(in,IsMac,8);
- if (!strcmp(IsMac,"FSSDSFX!"))
- ConvertMAC(Opt);
- else
- GuidoCheck(Opt);
- }
- }
- ConvertRaw(Opt);
- }
-
- /* This routine is a modified version of Guido van Rossum's (guido@cwi.nl)
- * 'whatsound' routine. It guesses the sound file type (signed/unsigned/u-law)
- * by checking how the values in the file are distributed. Thanks Guido!!
- */
-
- void GuidoCheck(struct options *Opt)
- {
- LONG a,n;
- ULONG bin[4];
- int x;
-
-
- Opt->InType=RAW;
- for (a=0; a<4; a++)
- bin[a]=0;
- do
- {
- n=Read(in,Opt->Data,Opt->BuffSize);
- for(a=0; a<n; a++)
- bin[(UBYTE)Opt->Data[a]/64]++;
- }
- while (n==Opt->BuffSize);
- if((bin[2]==0) && (bin[3]==0))
- CleanUp(Opt,7);
-
- x=((bin[0]+bin[3])*100)/(bin[1]+bin[2]);
-
- if(x>=300)
- Opt->InSign=TRUE;
- else if ( x <= 33)
- Opt->InSign=FALSE;
- else if ( (x >= 50) && (x <= 200))
- {
- Opt->MuLawIn=TRUE;
- if(Opt->SampRate==0) Opt->SampRate=8000;
- }
-
- if(!Opt->SampRate)
- Opt->SampRate=11395;
- Seek(in,0,OFFSET_END);
- Opt->Size=Seek(in,0,OFFSET_BEGINNING);
- }
-
-
- void ConvertRaw(struct options *Opt)
- {
- LONG b_read,i,scale,b_written,total,t,BuffSize;
- int max;
- signed char logs[256];
- unsigned char ulawbytes[256];
- BPTR op=Output();
- BYTE max2=0, *Data, x;
-
-
- if(AFlag)
- switch (Opt->OutType)
- {
- case IFF : strcat(Opt->outname,".iff");
- break;
-
- case RAW : strcat(Opt->outname,".raw");
- break;
-
- case AU : strcat(Opt->outname,".au");
- break;
-
- default : strcat(Opt->outname,".out");
- }
-
- if((out=(struct FileHandle *)Open(Opt->outname,MODE_NEWFILE))==NULL)
- CleanUp(Opt,8);
-
- if (Opt->MuLawIn && (!Opt->MuLawOut))
- {
- Opt->Amp=3;
- max=getscale(Opt);
- maketable(logs,max);
- if (Opt->InType==AU)
- Seek(in,32,OFFSET_BEGINNING);
- else
- Seek(in,0,OFFSET_BEGINNING);
- }
-
- if (Opt->MuLawOut && (!Opt->MuLawIn))
- maketableII(ulawbytes);
-
- scale=Opt->Bits/8;
-
- if (!Opt->Amp)
- {
- LONG tmppos;
- BYTE a;
-
- total=0;
- tmppos=Seek(in,0,OFFSET_CURRENT);
- do
- {
- b_read=Read(in,Opt->Data,Opt->BuffSize)/scale;
- for(i=0; i<b_read; i++)
- max2=MAX(max2,Opt->Data[i*scale]);
- total+=b_read;
- }
- while (total < Opt->Size);
- Seek(in,tmppos,OFFSET_BEGINNING);
- }
-
- if(Opt->NewRate)
- Opt->Size = Opt->Size * Opt->NewRate / Opt->SampRate;
-
- PrintIOInfo(Opt);
-
- switch (Opt->OutType)
- {
- case IFF : WriteIFFStuff(Opt); break;
- case AU : WriteAUStuff(Opt); break;
- }
-
- if ( Opt->FibDeltIn )
- {
- BuffSize = Opt->BuffSize >> 1;
- Data = Opt->Data + BuffSize;
- Read (in, &x, 1);
- Read (in, &x, 1);
- }
- else
- {
- BuffSize = Opt->BuffSize;
- Data = Opt->Data;
- }
-
- total=0;
- do
- {
- b_read=Read(in, Data, BuffSize)/scale;
-
- if (Opt->FibDeltIn)
- {
- x = D1Unpack(Data,b_read,Opt->Data,x);
- b_read <<= 1;
- }
-
- if(Opt->MuLawIn && (!Opt->MuLawOut))
- for (i=0; i<b_read; i++)
- Opt->Data[i]=logs[(UBYTE)Opt->Data[i]];
- else
- {
- if(scale!=1)
- for (i=0; i<b_read; i++)
- Opt->Data[i]=Opt->Data[i*scale];
-
- if(Opt->Amp && (Opt->Amp!=3))
- for (i=0; i<b_read; i++)
- Opt->Data[i]=Opt->Amp*Opt->Data[i]/3;
- else if((Opt->Amp==0) && (max2 != 127))
- for (i=0; i<b_read; i++)
- Opt->Data[i]=Opt->Data[i]*127/max2;
- }
-
- if(Opt->NewRate)
- {
- for(t=0; t<(b_read * Opt->NewRate / Opt->SampRate); t++)
- Opt->Data[t]=Opt->Data[t * Opt->SampRate / Opt->NewRate];
- b_read = b_read * Opt->NewRate / Opt->SampRate;
- }
-
- if(Opt->InSign != Opt->OutSign)
- for (i=0; i<b_read; i++)
- Opt->Data[i] ^= 0x80;
-
- if(Opt->MuLawOut && (!Opt->MuLawIn))
- for (i=0; i<b_read; i++)
- Opt->Data[i] = ulawbytes[(unsigned char)Opt->Data[i]];
-
- total+=b_read;
-
- b_written=Write(out,Opt->Data,b_read);
- FileLen+=b_written;
- if(b_written!=b_read) CleanUp(Opt,10);
- }
- while((total < Opt->Size) && (b_read > 0));
-
- if((Opt->OutType == IFF) && (total & 1))
- FileLen+=Write(out,'\0',1);
-
- if(Opt->OutType == IFF)
- FixSize(Opt, total);
-
- CleanUp(Opt,0);
- }
-
- void FixSize(struct options *Opt, ULONG total)
- {
- FileLen-=8;
- Seek(out,4,OFFSET_BEGINNING);
- Write(out,&FileLen,4);
- Seek(out,BodySpot+4,OFFSET_BEGINNING);
- Write(out,&total,4);
- Seek(out,20,OFFSET_BEGINNING);
- Write(out,&total,4);
- }
-
-
- void WriteIFFStuff(struct options *Opt)
- {
- ULONG i;
- ChunkHeader Head;
- time_t t;
- struct tm *tp;
- char datetime[50];
-
- Voice8Header V8H = {0,0,32,8363,1,0,Unity};
-
- Head.ckID = FORM;
- Head.ckSize = 0;
-
- FileLen+=Write(out,&Head,8);
-
- i=ID_8SVX;
- FileLen+=Write(out,&i,4);
-
- Head.ckID = ID_VHDR;
- Head.ckSize = 20;
- FileLen+=Write(out,&Head,8);
-
- V8H.oneShotHiSamples = 0;
- V8H.samplesPerSec = Opt->NewRate ? Opt->NewRate : Opt->SampRate;
- FileLen+=Write(out,&V8H,20);
-
- if (!Opt->KillChunk)
- {
- i=strlen(Opt->FileName);
- printf("NAME: %s\n",Opt->FileName);
- Head.ckID = ID_NAME;
- Head.ckSize = i;
- FileLen+=Write(out,&Head,8);
- FileLen+=Write(out,Opt->FileName,i);
- FileLen+=Write(out,'\0',i & 1);
-
- if(!Opt->Auth)
- {
- if(!(Opt->Auth=(char *)malloc(strlen(SZVER)+25)))
- CleanUp(Opt,5);
- strcpy(Opt->Auth,SZVER);
- strcat(Opt->Auth," by mrc113@psuvm.psu.edu");
- }
- i=strlen(Opt->Auth);
- printf("AUTH: %s\n",Opt->Auth);
- Head.ckID = ID_AUTH;
- Head.ckSize = i;
- FileLen+=Write(out,&Head,8);
- FileLen+=Write(out,Opt->Auth,i);
- FileLen+=Write(out,'\0',i & 1);
-
-
- t=time(NULL);
- tp=localtime(&t);
- i=strftime(datetime,49,"Converted: %d %b %Y %X by SoundZAP",tp);
- printf("ANNO: %s\n",datetime);
- Head.ckID = ID_ANNO;
- Head.ckSize = i;
- FileLen+=Write(out,&Head,8);
- FileLen+=Write(out,datetime,i);
- FileLen+=Write(out,'\0',i & 1);
-
- if(strlen(Opt->Copy))
- {
- i=strlen(Opt->Copy);
- printf("Copyright: %s\n",Opt->Copy);
- Head.ckID = ID_Copyright;
- Head.ckSize = i;
- FileLen+=Write(out,&Head,8);
- FileLen+=Write(out,Opt->Copy,i);
- FileLen+=Write(out,'\0',i & 1);
- }
- }
-
- BodySpot=Seek(out,0,OFFSET_CURRENT);
-
- Head.ckID = ID_BODY;
- Head.ckSize = 0L;
- FileLen+=Write(out,&Head,8);
- }
-
- void WriteAUStuff(struct options *Opt)
- {
- AUHeader AUH;
-
- AUH.magic=0x2e736e64; /* '.snd' */
- AUH.hrd_size=24;
- AUH.channels=1;
- AUH.sample_rate=8000;
- Opt->NewRate=8000;
- AUH.encoding=1;
- AUH.data_size=0;
- FileLen+=Write(out,&AUH,24);
- }
-
- void PrintIOInfo(struct options *Opt)
- {
- printf("\n%s -> %s\n\n",Opt->inname,Opt->outname);
- printf("Convert from ");
- switch (Opt->InType)
- {
- case IFF : printf("IFF 8SVX to "); break;
- case AU : printf(".au to "); break;
- case RAW : printf("Raw data to "); break;
- case AIFF : printf("AIFF to "); break;
- case VOC : printf(".voc to "); break;
- case WAV : printf(".wav to "); break;
- case MAC : printf("Macintosh to "); break;
- default : printf(" <UNKNOWN> to ");
- }
- switch (Opt->OutType)
- {
- case IFF : printf("IFF 8SVX\n"); break;
- case AU : printf(".au\n"); break;
- case RAW : printf("Raw data\n"); break;
- /*
- case AIFF : printf("AIFF\n"); break;
- case VOC : printf(".voc\n"); break;
- case WAV : printf(".wav\n"); break;
- case MAC : printf("Macintosh\n"); break;
- */
- default : printf(" <UNKNOWN>\n");
- }
- printf("\nInput data is ");
- if(Opt->MuLawIn)
- printf("u-lawed, ");
- else
- printf(Opt->InSign ? "signed, " : "unsigned, ");
- if (Opt->FibDeltIn) printf("Fibonacci Delta encoded, ");
- printf("and the output data is ");
- if(Opt->MuLawOut)
- printf("u-lawed\n");
- else
- printf(Opt->OutSign ? "signed\n" : "unsigned\n");
-
- printf("Input data is %d bits per sample, %d samples per second\n",Opt->Bits,Opt->SampRate);
-
- if (Opt->NewRate)
- printf("Output data is re-sampled to %d samples per second\n",Opt->NewRate);
-
- printf("\nBuffer size: %d bytes\n",Opt->BuffSize);
-
- if(!Opt->Amp)
- printf("\nOutput data amplified to maximum\n");
- else if (Opt->Amp != 3)
- printf("\nOutput data amplified %d thirds times\n",Opt->Amp);
-
- if(Opt->OutType == IFF)
- if(Opt->KillChunk) printf("\nSuppress extra chunk creation\n");
- else printf("\nChunks to be written to IFF file:\n");
- }
-
- void ConvertVOC(struct options *Opt)
- {
- UBYTE c[2];
-
- if(!Opt->SampRate)
- {
- Seek(in,30,OFFSET_BEGINNING);
- Read(in,c,2);
- if(c[1]!=0)
- CleanUp(Opt,9);
- Opt->SampRate=1000000/(256-c[0]);
- }
- Opt->InSign=FALSE;
- Seek(in,0,OFFSET_END);
- Opt->Size=Seek(in,0,OFFSET_BEGINNING)-32;
- Seek(in,32,OFFSET_BEGINNING);
- Opt->InType=VOC;
- }
-
- void ConvertWAV(struct options *Opt)
- {
- ChunkHeader Head;
- ULONG FileSize;
- ULONG FileType;
- LONG b_read;
- WaveFmtChunk fmt;
-
- Seek(in,0,OFFSET_BEGINNING);
- Read(in,&Head,8);
- if(Head.ckID != RIFF)
- CleanUp(Opt,12);
- FileSize = SCREWINTEL(Head.ckSize);
-
- b_read=Read(in,&FileType,4);
- if(FileType != WAVE)
- CleanUp(Opt,12);
-
- while((Head.ckID != DATA) && b_read)
- {
- b_read = Read(in,&Head,8);
- if (b_read)
- {
- Head.ckSize = SCREWINTEL(Head.ckSize);
- if (Head.ckID == FMT)
- {
- Read(in,&fmt,sizeof(WaveFmtChunk));
- if(fmt.wChannels != 0x0100)
- CleanUp(Opt,15);
- if(fmt.wFormatTag != 0x0100)
- CleanUp(Opt,9);
- Opt->SampRate = SCREWINTEL(fmt.dwSamplesPerSec);
- Seek(in,Head.ckSize - sizeof(WaveFmtChunk),OFFSET_CURRENT);
- }
- else if (Head.ckID == DATA)
- Opt->Size = SCREWINTEL(Head.ckSize);
- else
- Seek(in,(SCREWINTEL(Head.ckSize) + 1) & ~1 ,OFFSET_CURRENT);
- }
- }
- Opt->InSign=FALSE;
- Opt->InType=WAV;
- }
-
- void ConvertMAC(struct options *Opt)
- {
- USHORT len;
- char *name;
-
- Opt->InSign=FALSE;
- Seek(in,0,OFFSET_END);
- Opt->Size=Seek(in,0,OFFSET_BEGINNING)-668;
- Read(in,&len,2);
- name=(char *)malloc(len);
- Read(in,name,len);
- name[len]='\0';
- strcpy(Opt->FileName,name);
- Seek(in,128,OFFSET_BEGINNING);
- if (!Opt->SampRate)
- Opt->SampRate=11395;
- free(name);
- Opt->InType=MAC;
- }
-
- /* Thanks to Sean Connolly for sending me info on the .au sound format.*/
-
- void ConvertAU(struct options *Opt)
- {
- AUHeader AUHdr;
-
- Seek(in,0,OFFSET_END);
- Opt->Size=Seek(in,0,OFFSET_BEGINNING)-32;
- Read(in,&AUHdr,28);
- switch (AUHdr.encoding)
- {
- case 1 : Opt->MuLawIn=TRUE;
- break;
-
- case 2 : Opt->Bits=8;
- break;
-
- case 3 : Opt->Bits=16;
- Opt->Size/=2;
- break;
-
- case 4 : Opt->Bits=24;
- Opt->Size/=3;
- break;
-
- case 5 : Opt->Bits=32;
- Opt->Size/=4;
- break;
-
- default : CleanUp(Opt,9);
- break;
- }
-
- if (!Opt->SampRate)
- Opt->SampRate=AUHdr.sample_rate;
-
- Opt->InType=AU;
- }
-
- void ConvertIFF(struct options *Opt)
- {
- struct ChunkInfo List, *This, *Next;
- Voice8Header V8H;
- CommonChunk CC;
- char *data;
- int Help=0;
- BOOL Flag=TRUE;
-
- List=GetChunks(Get,9,in);
-
- if (List.Next == NULL)
- Help=11;
- else
- {
- switch(List.Name)
- {
- case ID_8SVX : Opt->InType=IFF; break;
- case ID_AIFF : Opt->InType=AIFF; break;
- default : Help=11;
- }
- }
-
- Next=List.Next;
- while(Next)
- {
- This=Next;
- Seek(in,This->Pos,OFFSET_BEGINNING);
- switch(This->Name)
- {
- case ID_COMM : Read(in,&CC,18);
- Opt->Size=CC.numSampleFrames;
- Opt->Bits=(CC.sampleSize+7)/8;
- Opt->Bits*=8;
- break;
-
- case ID_SSND : Seek(in,8,OFFSET_CURRENT); /*Don't use it for anything so just get to the right place */
- break;
-
- case ID_VHDR : Read(in,&V8H,20);
- if (!Opt->SampRate)
- Opt->SampRate=V8H.samplesPerSec;
- if(V8H.sCompression) Opt->FibDeltIn=TRUE;
- break;
-
- case ID_BODY : Opt->Size=This->Size;
- break;
-
- /* AUTH and Copyright must be preserved! */
-
- case ID_AUTH : if(!(Opt->Auth=(char *)malloc(This->Size)))
- CleanUp(Opt,5);
- Read(in,Opt->Auth,This->Size);
- Opt->Auth[This->Size]='\0';
- if (!strncmp(Opt->Auth,"SoundZAP",8))
- {
- free(Opt->Auth);
- Opt->Auth=NULL;
- }
- break;
-
- case ID_Copyright : if(!(Opt->Copy=(char *)malloc(This->Size)))
- CleanUp(Opt,5);
- Read(in,Opt->Copy,This->Size);
- Opt->Copy[This->Size]='\0';
- break;
-
- case ID_NAME : if(!(data=(char *)malloc(This->Size)))
- CleanUp(Opt,5);
- Read(in,data,This->Size);
- data[This->Size]='\0';
- if (Flag) printf("Chunks found but not preserved:\n");
- printf("NAME: %s\n",data);
- free(data);
- Flag=FALSE;
- break;
-
- case ID_ANNO : if(!(data=(char *)malloc(This->Size)))
- CleanUp(Opt,5);
- Read(in,data,This->Size);
- data[This->Size]='\0';
- if (Flag) printf("Chunks found but not preserved:\n");
- Flag=FALSE;
- printf("ANNO: %s\n",data);
- free(data);
- break;
-
- case ID_TEXT : if(!(data=(char *)malloc(This->Size)))
- CleanUp(Opt,5);
- Read(in,data,This->Size);
- data[This->Size]='\0';
- if (Flag) printf("Chunks found but not preserved:\n");
- Flag=FALSE;
- printf("TEXT: %s\n",data);
- free(data);
- break;
- }
- Next=This->Next;
- free(This);
- }
- if (Help)
- CleanUp(Opt,Help);
- }
-
-
- /*--------------------------------------------------------------------------*
- * The following routine was extracted from posting by Brian Foley. *
- * Brian Foley email: bfoley@greatlakes.Central.Sun.COM *
- * Systems Engineer smail: 1000 Town Center *
- * Sun Microsystems Suite 1700 *
- * GreatLakes Region Southfield, MI 48075 (313) 352-7070 *
- *--------------------------------------------------------------------------*/
-
- int ulaw2linear(unsigned char ulawbyte)
- {
- static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
- int sign, exponent, mantissa, sample;
-
- ulawbyte = ~ulawbyte;
- sign = ulawbyte & 0x80;
- exponent = (ulawbyte >> 4) & 0x07;
- mantissa = ulawbyte & 0x0F;
- sample = (exp_lut[exponent] + (mantissa << (exponent + 3)));
- if ( sign ) sample = -sample;
- return sample;
- }
-
- int getscale(struct options *Opt)
- {
- int count, max = 0, i;
-
- do
- {
- count = Read(in, Opt->Data, Opt->BuffSize);
- for ( i = 0; i < count; i++ )
- max = MAX(abs(ulaw2linear(Opt->Data[i])), max);
- }
- while ( count == Opt->BuffSize );
-
- return max;
- }
-
- void maketable(signed char *logs, int max)
- {
- int i, c, d;
-
- for ( i = 0; i < 256; i++ )
- {
- c = ( ulaw2linear(i) * ulaw2linear(0) ) / max;
- d = abs(c) & 0xFF;
- if ( d > 0x7F )
- if ( c > 0 )
- logs[i] = (signed char) ( c / 256 + 1 );
- else
- logs[i] = (signed char) ( c / 256 - 1 );
- else
- logs[i] = (signed char) ( c / 256 );
- }
- }
-
- void maketableII(unsigned char *ubytes)
- {
- signed int i;
-
- for(i=0; i<256; i++)
- ubytes[i]=st_linear_to_ulaw((signed char)i);
- }
-
- /*
- ** This routine converts from linear to ulaw.
- **
- ** Craig Reese: IDA/Supercomputing Research Center
- ** Joe Campbell: Department of Defense
- ** 29 September 1989
- **
- ** References:
- ** 1) CCITT Recommendation G.711 (very difficult to follow)
- ** 2) "A New Digital Technique for Implementation of Any
- ** Continuous PCM Companding Law," Villeret, Michel,
- ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
- ** 1973, pg. 11.12-11.17
- ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
- ** for Analog-to_Digital Conversion Techniques,"
- ** 17 February 1987
- **
- ** Input: Signed 16 bit linear sample
- ** Output: 8 bit ulaw sample
- */
-
- #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
- #define CLIP 32635
-
- unsigned char st_linear_to_ulaw( signed char oldsample )
- {
- static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
- int sign, exponent, mantissa, sample;
- unsigned char ulawbyte;
-
- sample=oldsample << 8;
- /* Get the sample into sign-magnitude. */
- sign = (sample >> 8) & 0x80; /* set aside the sign */
- if ( sign != 0 ) sample = -sample; /* get magnitude */
- if ( sample > CLIP ) sample = CLIP; /* clip the magnitude */
-
- /* Convert from 16 bit linear to ulaw. */
- sample = sample + BIAS;
- exponent = exp_lut[( sample >> 7 ) & 0xFF];
- mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
- ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
- /*
- if ( ulawbyte == 0 ) ulawbyte = 0x02;
- */
- return ulawbyte;
- }
-
- struct ChunkInfo GetChunks(ULONG *Names, int n, struct FileHandle *in)
- {
- LONG Size, pos=0,b_read;
- ChunkHeader Head;
- struct ChunkInfo List, *ThisNode;
- ID Type;
- int i;
-
- Seek(in,0,OFFSET_END);
- Size=Seek(in,0,OFFSET_BEGINNING);
- if(Size < 50)
- {
- List.Size=ERROR_IN_FORM;
- List.Next=NULL;
- return List;
- }
-
- pos+=Read(in,&Head,8);
- if (Head.ckID != FORM)
- {
- List.Size=ERROR_IN_FORM;
- List.Next=NULL;
- return List;
- }
-
- pos+=Read(in,&List.Name,4);
-
- b_read=Read(in,&Head,8);
- ThisNode=&List;
- do
- {
- pos+=b_read;
- for (i=1; i<n; i++)
- if (Head.ckID == Names[i])
- {
- if((ThisNode->Next=(void *)malloc(16))==NULL)
- {
- List.Size=NO_MEMORY;
- return List;
- }
-
- ThisNode=ThisNode->Next;
- ThisNode->Next = NULL;
- ThisNode->Name = Head.ckID;
- ThisNode->Size = Head.ckSize;
- ThisNode->Pos = pos;
- }
- Seek(in,Head.ckSize+(Head.ckSize & 1),OFFSET_CURRENT);
- pos+=Head.ckSize+(Head.ckSize & 1);
- b_read=Read(in,&Head,8);
- }
- while ((ThisNode->Name!=ID_BODY) && (b_read==8));
-
- List.Size=GOOD_FILE;
- return List;
- }
-